﻿using HandyControl.Controls;
using HandyControl.Data;
using log4net;
using MaterialTypeRecognition.Shell.Geometries;
using MaterialTypeRecognition.Shell.Logs;
using MaterialTypeRecognition.Shell.Uers;
using Microsoft.Extensions.DependencyInjection;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;

namespace MaterialTypeRecognition.Shell.ViewModels
{
    public class UserManagerWindowViewModel : BindableBase
    {
        private const string GrowlToken = "UserManagerToken";

        private readonly IUserService _userService;

        private readonly ILog _operationLog;

        public UserManagerWindowViewModel(IServiceProvider services, ILog4NetLoggerFactory factory)
        {
            _operationLog = factory.GetOperationLogger();
            UserViewModels = new ObservableCollection<UserViewModel>();
            var scopeServices = services.CreateScope();
            _userService = scopeServices.ServiceProvider.GetRequiredService<IUserService>();
            var awaiter = _userService.GetAllAsync().GetAwaiter();
            awaiter.OnCompleted(() =>
            {
                var users = awaiter.GetResult();
                users.ForEach(user =>
                {
                    var tempUser = new UserViewModel()
                    {
                        UserName = user.UserName,
                    };
                    if (user.Permission == UserPermissoins.Users.OPN)
                    {
                        tempUser.UserPermission = UserPermissions.OPN;
                    }
                    else if (user.Permission == UserPermissoins.Users.OPNMonitor)
                    {
                        tempUser.UserPermission = UserPermissions.OPNMonitor;
                    }
                    else if (user.Permission == UserPermissoins.Users.ME)
                    {
                        tempUser.UserPermission = UserPermissions.ME;
                    }
                    else if (user.Permission == UserPermissoins.Users.PE)
                    {
                        tempUser.UserPermission = UserPermissions.PE;
                    }
                    else if (user.Permission == UserPermissoins.Users.Admin)
                    {
                        tempUser.UserPermission = UserPermissions.Admin;
                    }
                    else
                    {
                        tempUser.UserPermission = UserPermissions.OPN;
                    }

                    UserViewModels.Add(tempUser);
                });
            });

            RegisterCommand = new DelegateCommand<object>(OnRegister);
            UnregisterCommand = new DelegateCommand<object>(OnUnregister);
            RefreshCommand = new DelegateCommand(OnRefresh);
        }

        private string? _userName;

        public string? UserName
        {
            get { return _userName; }
            set
            {
                SetProperty(ref _userName, value);
            }
        }

        /// <summary>
        /// 选择的权限索引。
        /// </summary>
        public int PermissionsSelectedIndex { get; set; } = 0;

        public ObservableCollection<UserViewModel> UserViewModels { get; set; }

        public ICommand RegisterCommand { get; set; }

        private async void OnRegister(object element)
        {
            var passwordBox = (PasswordBox)element;
            var password = passwordBox.Password;

            if (string.IsNullOrWhiteSpace(UserName))
            {
                ShowInfo("请输入用户名！", true);
            }
            else if (UserName.Contains(" "))
            {
                ShowInfo("用户名不能包含空格符！");
            }
            else if (UserName.Length < 6 || UserName.Length > 20)
            {
                ShowInfo("用户名长度为6至20个字符！", true);
            }
            else if (string.IsNullOrWhiteSpace(password))
            {
                ShowInfo("卡号不能为空！", true);
            }
            else if (password.Any(charItem => charItem < '0' || charItem > '9'))
            {
                ShowInfo("卡号只能包含数字字符！", true);
            }
            else
            {
                await RegisterUserAsync(new UserDto()
                {
                    Key = password,
                    UserName = UserName,
                    Permission = GetMesConfigurationPermission(PermissionsSelectedIndex)
                });

                passwordBox.Password = string.Empty;
                
            }
        }

        private async Task RegisterUserAsync(UserDto user)
        {
            try
            {
                await _userService.RegisterAsync(user);
                ShowInfo("注册用户成功！");
                _operationLog.Info($"注册新用户：{user.UserName}");
                UserName = string.Empty;
            }
            catch (Exception)
            {
                ShowInfo("注册用户失败！", true);
            }
        }

        private string GetMesConfigurationPermission(int index)
        {
            return index switch
            {
                0 => UserPermissoins.Users.OPN,
                1 => UserPermissoins.Users.OPNMonitor,
                2 => UserPermissoins.Users.ME,
                3 => UserPermissoins.Users.PE,
                4 => UserPermissoins.Users.Admin,
                _ => UserPermissoins.Users.OPN,
            };
        }

        public ICommand UnregisterCommand { get; set; }

        private async void OnUnregister(object element)
        {
            var passwordBox = (PasswordBox)element;
            var password = passwordBox.Password;

            if (string.IsNullOrWhiteSpace(password))
            {
                ShowInfo("请输入有效的Key！", true);
            }
            else
            {
                try
                {
                    await _userService.UnregisterAsnyc(password);
                    ShowInfo("注销用户成功！");
                }
                catch (Exception)
                {
                    ShowInfo("注销用户失败！", true);
                }

                passwordBox.Password = string.Empty;
            }
        }

        public ICommand RefreshCommand { get; set; }

        private async void OnRefresh()
        {
            List<UserInfoDto> users;

            try
            {
                users = await _userService.GetAllAsync();
            }
            catch (Exception)
            {
                ShowInfo("刷新用户列表失败！", true);
                return;
            }

            UserViewModels.Clear();

            users.ForEach(user =>
            {
                var tempUser = new UserViewModel()
                {
                    UserName = user.UserName,
                };

                if (user.Permission == UserPermissoins.Users.OPN)
                {
                    tempUser.UserPermission = UserPermissions.OPN;
                }
                else if (user.Permission == UserPermissoins.Users.OPNMonitor)
                {
                    tempUser.UserPermission = UserPermissions.OPNMonitor;
                }
                else if (user.Permission == UserPermissoins.Users.ME)
                {
                    tempUser.UserPermission = UserPermissions.ME;
                }
                else if (user.Permission == UserPermissoins.Users.PE)
                {
                    tempUser.UserPermission = UserPermissions.PE;
                }
                else if (user.Permission == UserPermissoins.Users.Admin)
                {
                    tempUser.UserPermission = UserPermissions.Admin;
                }
                else
                {
                    tempUser.UserPermission = UserPermissions.OPN;
                }

                UserViewModels.Add(tempUser);
            });

            ShowInfo("刷新用户列完成！");
        }

        private void ShowInfo(string message, bool isWarning = false)
        {
            var info = new GrowlInfo()
            {
                ShowDateTime = false,
                ShowCloseButton = true,
                WaitTime = 1,

                Token = GrowlToken
            };

            info.Message = message;

            if (isWarning)
            {
                info.IconBrush = Brushes.Red;
                info.Icon = Icons.ErrorIcon;
                Growl.Warning(info);
            }
            else
            {
                info.IconBrush = Brushes.Green;
                info.Icon = Icons.SuccessIcon;
                Growl.Info(info);
            }
        }
    }
}
